

#include <iostream>
#include <cassert>
#include <array>
#include "param_airfoil_hicksHenne.hpp"
using namespace std;

inline void print(const point<double> &p)
{
    cout << "\n"
         << p.x << "\t"
         << p.y << "\t"
         << p.z << "\n";
}

inline void print(const VarArray<double, 2> &arr, ostream &os)
{
    os << scientific << setprecision(3);
    for (int i = 0; i < arr.Dim(0); ++i)
    {
        for (int j = 0; j < arr.Dim(1); ++j)
        {
            os << arr(i, j) << "\t";
            os.flush();
        }
        os << endl;
    }
    os << endl;
}

using vec3 = double[3];

int main()
{
    // 从文件中读主要是测试  赋值的也测试过了
    cout << "start running ........\n";

    // string grid{"airfoil.dat"};
    // 提供的翼型数据请保持 首尾顶点 在 首尾(尾首) 即按两个线段输出
    string grid{"foil1200.dat"};
    Airfoil<double> af(grid);
    // af.print(cout);

#if 0
    af.print(cout);
    point<double> head, tail;
    head = af.getHead();
    tail = af.getTail();

    print(head);
    print(tail);
#endif

    array<double, 4> up_pos{0.25, 0.5, 0.75, 0.97}, low_pos{up_pos};
    array<double, 4> up_delta{1e-3, 1e-3, 1e-3, 1e-3}, low_delta{up_delta};
    // cout << low_pos.size() << "\n" << low_pos[2] << "\n";
    vector<double> deltaY;
    string str;

    VarArray<double, 2> derivativeMat;

#ifdef NOTSAME
    str = "NotSame";
    deltaY = GetDeltaY_notSame((vec3 *)af.dataUp(), af.sizeUp(), (vec3 *)af.dataLow(),
                               af.sizeLow(), up_delta.data(), up_pos.data(),
                               up_pos.size(), low_delta.data(),
                               low_pos.data(), low_pos.size(), derivativeMat);
#else
    str = "Same";
    deltaY = GetDeltaY_same((vec3 *)af.dataUp(), af.sizeUp(),
                            (vec3 *)af.dataLow(), af.sizeLow(),
                            up_delta.data(), low_delta.data(),
                            up_pos.data(), up_pos.size(), derivativeMat);
#endif

    int up_size{af.sizeUp()}, low_size{af.sizeLow()};
    point<double> *up_coord{af.dataUp()}, *low_coord{af.dataLow()};
// 输出修改后的数据到文件里  pointwise segment 格式  但导入时需要尝试多次
#if 1
    str = "modified" + str + ".dat";
    ofstream os{str};
    os << std::scientific << std::setprecision(15);
    os << up_size << "\n";
    for (int i = 0; i < up_size; ++i)
    {
        os << up_coord[i].x << "\t"
           << up_coord[i].y + deltaY[i] << "\t"
           << up_coord[i].z << "\n";
    }
    os << low_size << "\n";
    for (int i = 0; i < low_size; ++i)
    {
        os << low_coord[i].x << "\t"
           << low_coord[i].y + deltaY[i + up_size] << "\t"
           << low_coord[i].z << "\n";
    }
    os.close();
// 输出原始翼型坐标   无重复  二进制
#if 1
    string binOriFoil{"ori.plt"};
    ofstream fbinOriFoil{binOriFoil, ios_base::binary};

    int node_num = up_size + low_size - 2;
    fbinOriFoil.write(reinterpret_cast<char *>(&node_num), sizeof(node_num));
    fbinOriFoil.write(reinterpret_cast<char *>(up_coord), sizeof(point<double>) * up_size);
    // 提供的翼型首尾点就是第一个和最后一个(谁前谁后不分)
    fbinOriFoil.write(reinterpret_cast<char *>(low_coord + 1), sizeof(point<double>) * (low_size - 2));
    fbinOriFoil.close();

    // 输出计算的 deltaY  与上面坐标一一对应
    string fn{"disp_y.dat"};
    ofstream fbinDeltaY{fn, ios_base::binary};
    fbinDeltaY.write(reinterpret_cast<char *>(&node_num), sizeof(node_num));
    fbinDeltaY.write(reinterpret_cast<char *>(deltaY.data()),
                     sizeof(double) * up_size);
    // 去除首尾重点
    fbinDeltaY.write(reinterpret_cast<char *>(deltaY.data() + up_size + 1), sizeof(double) * (low_size - 2));
    fbinDeltaY.close();

    // 输出 导数矩阵  与上面的一一对应
    int num_pos = low_pos.size() + up_pos.size();
    string mat{"derivativeMat.bin"};
    ofstream fmat{mat, ios_base::binary};
    fmat.write(reinterpret_cast<char *>(&node_num), sizeof(node_num));
    fmat.write(reinterpret_cast<char *>(&num_pos), sizeof(num_pos));
    fmat.write(reinterpret_cast<char *>(derivativeMat.data()), sizeof(double) * up_size * num_pos);
    fmat.write(reinterpret_cast<char *>(derivativeMat.data() + (up_size + 1) * num_pos), sizeof(double) * (low_size - 2) * num_pos);
    fmat.close();
#endif

#if 0
    for(int i = 0; i < deltaY.size(); ++i)
    {
        cout << deltaY[i] << "\n";
    }
#endif

#endif

#if 0
    ofstream fderiMat{"derivativeMat.dat"};
    cout << derivativeMat.Dim(1) << endl;
    print(derivativeMat, fderiMat);
    fderiMat.close();
#endif
    cout << "....... end!\n";
    return 0;
}